import core from '@/core/'
import Moni from '@/core/request/ApiMoni'

// 启动时需要清理的存储信息。须保留一个对外
const ClearKey = {
	/**
	 * 用户的缓存信息的key值
	 * 每次启动时要清理，以免Key值无限累积
	 */
	UserInfoCache: 'KeyForUserInfoCache',
	/**
	 * 请求的缓存信息的key值
	 * 每次启动时要清理，以免Key值无限累积
	 */
	RequestCache: 'KeyForRequestCache',
}
// 记录用户缓存的key值。该值在启动初始化时不会被赋值
const userInfoIds = []

// 异步获取数据
const getData = (key) => {
	return new Promise((resolve, reject) => {
		if (key) {
			uni.getStorage({
				key,
				success: (res) => {
					resolve(res.data)
				},
				fail: err => {
					resolve('')
				}
			})
		} else {
			resolve('')
		}
	})
}

// 同步获取数据
const getDataSync = (key) => {
	if (key) {
		return uni.getStorageSync(key)
	}
	return ''
}

// 异步存储数据
const setData = (key, data) => {
	return new Promise((resolve, reject) => {
		if (key && data !== undefined) {
			uni.setStorage({
				data, key,
				success: () => {
					resolve('success')
				},
				fail: reject
			})
		} else {
			reject('key值为空或者不符合要求')
		}
	})
}

// 同步存储数据
const setDataSync = (key, data) => {
	if (key && data !== undefined) {
		uni.setStorageSync(key, data)
	}
}

// 异步删除数据
const removeData = (key) => {
	return new Promise((resolve, reject) => {
		if (key) {
			uni.removeStorage({
				key,
				success: () => {
					resolve('success')
				},
				fail: reject
			})
		} else {
			reject('key值为空或者不符合要求')
		}
	})
}

// 同步删除数据
const removeDataSync = (key) => {
	if (key) {
		uni.removeStorageSync(key)
	}
}

// 异步清空数据
const clearData = () => {
	return uni.clearStorage()
}

// 同步清空数据
const clearDataSync = () => {
	uni.clearStorageSync()
}

/**
 * 存储信息的共同方法
 * 没有值传入时读取，有值传入时写入
 * forSync：写入时是否同步
 */
const common = (key, code = 'Only', res, forSync) => {
	key = `KeyFor${code}${key}`
	if (res) {
		if (res === 'clear') {
			// 清空相关信息
			return removeDataSync(key)
		}
		// 有值表示写入
		if (forSync) {
			return setDataSync(key, JSON.stringify(res))
		}
		// 默认是异步写入
		return setData(key, JSON.stringify(res))
	}
	// 没有值进来，表示是读取并返回，默认是同步读取
	const resJson = getDataSync(key)
	if (resJson) {
		res = JSON.parse(resJson)
	}
	return res
}

/**
 * 分类信息初始化组合对象
 * code：项目代码
 * res：得到的线上（或者其它途径）信息。该值需传，不通过info.user读取
 */
const CommonInitial = {
	// 用户信息
	user: (code, res) => {
		const result = common(`User`, code, res)
		if (!res) {
			res = result
		}
		if (res === 'clear') {
			core.user.initial()
		} else {
			if (res && typeof(res) === 'object') {
				core.user.initial(res, true)
			} else {
				core.user.initial()
			}
		}
		return result
	},
	// 项目信息
	target: (code, res) => {
		const result = common(`Target`, code, res)
		if (!res) {
			res = result
		}
		if (res === 'clear') {
			Object.keys(core.info.target).forEach(key => {
				delete core.info.target[key]
			})
		} else if (res && typeof(res) === 'object') {
			// 给项目信息赋值 - 清空原来值后再赋值
			core.synctool.copy.replace(res, core.info.target)
			// 给项目tabbar赋值
			if (res.tabbar && res.tabbar.length > 0) {
				core.store.tabbar.options = res.tabbar
			} else {
				core.store.tabbar.options = []
			}
		}
		return result
	},
	// 所有的接口信息
	api: (code, res) => {
		const result = common(`Api`, code, res)
		if (!res) {
			res = result
		}
		if (res === 'clear') {
			Object.keys(core.request.api).forEach(key => {
				delete core.request.api[key]
			})
		} else if (res) {
			// 给api接口信息赋值 - 清空原来值后再赋值
			core.synctool.copy.replace(res, core.request.api)
			if (core.isDevelopment) {
				// 开发状态下允许本地模拟的接口
				core.request.api.Moni = Moni
			}
		}
		return result
	},
	// 云服务空间信息
	basedata: (code, res) => {
		const result = common(`Basedata`, code, res)
		if (!res) {
			res = result
		}
		if (res === 'clear') {
			Object.keys(core.request.basedata).forEach(key => {
				delete core.request.basedata[key]
			})
		} else if (res) {
			// 解密云服务空间信息
			const {timestamp} = res
			delete res.timestamp
			res = core.synctool.basedata.deBasedata(res, timestamp)
			// 给云服务空间信息赋值 - 清空原来值后再赋值
			core.synctool.copy.replace(res, core.request.basedata)
			// 给云函数云对象赋值
			// core.request.initialCloud()
			// 找到当前项目所在的云服务空间
			const arr = Object.keys(core.request.basedata)
			for (let i = 0; i < arr.length; i++) {
				var name = arr[i]
				if (Object.prototype.toString.call(core.request.basedata[name]) === '[object Object]') {
					if (core.request.basedata[name].spaceId) { // 是云服务空间
						var {target} = core.request.basedata[name]
						if (target) {
							if (typeof(target) === 'string') {
								target = target.split(',')
							}
							if (Array.isArray(target) && target.indexOf(code) > -1) {
								// 找到当前项目所在的云服务空间
								core.request.basedata.current = name
								break
							}
						}
					}
				}
			}
			// 给文件上传的云服务空间赋值
			core.file.initial()
		}
		return result
	},
	
	// 字段的固定信息
	fixcolumns: (code, res) => {
		const result = common(`Fixcolumns`, code, res)
		if (!res) {
			res = result
		}
		if (res === 'clear') {
			Object.keys(core.request.fixcolumns).forEach(key => {
				delete core.request.fixcolumns[key]
			})
		} else if (res && typeof(res) === 'object') {
			// 给字段的固定信息赋值 - 清空原来值后再赋值
			core.synctool.copy.replace(res, core.request.fixcolumns)
		}
		return result
	},
	
	// 字典基础值信息
	basevalue: (code, res) => {
		const result = common(`Basevalue`, code, res)
		if (!res) {
			res = result
		}
		if (res === 'clear') {
			Object.keys(core.info.basevalue).forEach(key => {
				delete core.info.basevalue[key]
			})
		} else if (res && typeof(res) === 'object') {
			// 给字典基础值信息赋值 - 清空原来值后再赋值
			core.synctool.copy.replace(res, core.info.basevalue)
		}
		return result
	},
	
	// 主题信息
	theme: (code, res) => {
		const result = common(`Theme`, code, res)
		if (!res) {
			res = result
		}
		if (res === 'clear') {
			// 主题信息不处理
		} else if (Array.isArray(res) && res.length > 0) {
			// 得到的主题信息。返回的一定是数组。得到数组后，在core.theme中再进行初始化。不用对res进行存储
			core.theme.initial(res)
		}
		return result
	},
	
	// 多语言信息。如果与language中的date一致，不用考虑存储
	language: (code, res) => {
		var result
		if (!res || res.date !== core.language.date) {
			result = common(`Language`, code, res)
			if (!res) {
				res = result
			}
		}
		if (res && typeof(res) === 'object') {
			// 给多语言信息赋值 - 仅更新操作
			core.synctool.copy.update(res, core.language)
		}
		return result
	}
}

module.exports = {
	ClearKey, userInfoIds,
	getData, getDataSync,
	setData, setDataSync,
	clearData, clearDataSync,
	removeData, removeDataSync,
	
	// 该方法会在登录后再次执行，所以需要暴露出去
	user_initial: CommonInitial.user,
	
	// 清理用户缓存信息以及请求缓存信息
	initial() {
		// 读取存储的用户缓存key，并全部清空
		getData(ClearKey.UserInfoCache).then(res => {
			if (res) {
				res = JSON.parse(res)
				if (Array.isArray(res) && res.length > 0) {
					// 全部清空
					const cycle = (index = 0) => {
						if (index < res.length) {
							removeData(res[index]).then(res => {
								cycle(index + 1)
							}).catch(err => {
								cycle(index + 1)
							})
						} else {
							// 清空完成
							console.log('用户信息缓存清空完成')
						}
					}
					cycle()
				}
			}
		})
		// 读取存储的请求缓存key，并全部清空
		getData(ClearKey.RequestCache).then(res => {
			if (res) {
				res = JSON.parse(res)
				if (Array.isArray(res) && res.length > 0) {
					// 不清空的要重新记录下来
					const cycle = (index = 0) => {
						if (index < res.length) {
							if (res[index].substr(-6) === '-clear') {
								// -clear类型的信息要清空
								removeData(res[index]).then(res => {
									cycle(index + 1)
								}).catch(err => {
									cycle(index + 1)
								})
							} else {
								// -cache类型的信息不清空
								core.request.requestMd5s.push(res[index])
								cycle(index + 1)
							}
						} else {
							// 清空完成
							if (core.request.requestMd5s.length > 0) {
								setData(ClearKey.RequestCache, JSON.stringify(core.request.requestMd5s))
							}
							console.log('请求信息缓存清空完成')
						}
					}
					cycle()
				}
			}
		})
	},
	
	/**
	 * 清空相关的信息
	 * 启动失败，有可能是数据解析失败，会清除所有相关信息
	 */
	clear_initial(arr = Object.keys(CommonInitial), code = core.TargetCode) {
		Object.keys(CommonInitial).forEach(key => {
			if (arr.includes(key)) {
				CommonInitial[key](code, 'clear')
			}
		})
	},
	
	/**
	 * 根据项目代码，启动之前初始化
	 * 需读取以下信息：
	 * 	1，项目信息。非H5再网络不足时必须默认显示的内容
	 * 	2，用户信息。同上
	 * 	3，云服务空间信息
	 * 	4，基础值字典信息
	 * 	5，主题数组信息
	 * 	6，多语言新信息
	 */
	before_initial(code) {
		Object.keys(CommonInitial).forEach(key => {
			CommonInitial[key](code)
		})
	},
	
	/**
	 * 根据项目代码，启动之后拿到数据了再初始化
	 * 	1，项目信息
	 * 	2，云服务空间信息
	 * 	3，基础值字典信息
	 * 	4，主题数组信息
	 * 	5，多语言新信息
	 */
	after_initial(code, res) {
		const {data, user, api, basedata, fixcolumns, basevalue, theme, language, current, timeCost} = res
		Object.keys(CommonInitial).forEach(key => {
			switch (key){
				case 'target':
					CommonInitial[key](code, data)
					return
				case 'basedata':
					if (basedata) {
						basedata.timestamp = current - timeCost
					}
					break;
				case 'theme':
					if (theme && theme.length > 0) {
						break
					} else {
						return
					}
				default:
					break;
			}
			if (res[key]) {
				CommonInitial[key](code, res[key])
			}
		})
	},
}